package transport

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"lnzw/engine/actor"
	"lnzw/engine/encrypt"
	"lnzw/server/test/test_fyne/test_3/pbmsg"
	"strings"

	"google.golang.org/protobuf/proto"
)

func DefaultSyncSend(sourceId string, actorId string, pbmsg proto.Message) (actor.Msg, error) {
	bs, err := proto.Marshal(pbmsg)
	if err != nil {
		return actor.Msg{}, err
	}
	name := pbmsg.ProtoReflect().Descriptor().Name()
	namestr := string(name)
	if strings.HasPrefix(namestr, "Req") {
		rspnamestr := strings.Replace(namestr, "Req", "Res", 1)
		namestr = fmt.Sprintf("%s.%s", namestr, rspnamestr)
	}
	var buff bytes.Buffer
	binary.Write(&buff, binary.BigEndian, encrypt.Hash32(namestr))
	buff.Write(bs)
	return actor.SyncSend(sourceId, actorId, buff.Bytes())
}

func DefaultSyncSendWithRsp(sourceId string, actorId string, req proto.Message) (proto.Message, error) {
	msg, err := DefaultSyncSend(sourceId, actorId, req)
	if err != nil {
		return nil, err
	}
	rsp, err := DefaultReceive(msg)
	if err != nil {
		return nil, err
	}
	return rsp, nil
}

func DefaultReceive(msg actor.Msg) (proto.Message, error) {
	l := len(msg.Data)
	if l < 4 {
		return nil, errors.New("data error")
	}
	h := binary.BigEndian.Uint32(msg.Data[0:4])
	_, rsp := pbmsg.GetMsg(h)
	err := proto.Unmarshal(msg.Data[4:], rsp)
	if err != nil {
		return nil, err
	}
	return rsp, nil
}
